package geno.app.junit;

import static org.junit.Assert.*;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import geno.app.MyRectangle;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class RectangleTest {

	MyRectangle r;
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
	}

	@Before
	// will be performed before each test
	public void setUp() throws Exception {
		r=new MyRectangle(10,20);
	}

	@After
	// will be performed after each test
	public void tearDown() throws Exception {
	}
	
	// default value when object is created
	@Test
	public void testingDefaultValue() {
		// all values should be 0
		// After area reader is written.
		r = new MyRectangle();
		try
		{
			System.out.print("JUnit 4.0 Test [Assertions] - Default values : ");
			assertTrue("SUCCESS.", r.getHeight()==0 && r.getWidth()==0 && r.getArea()==0);
			System.out.println("SUCCESS.");
		}
		catch (AssertionError e)
		{
			System.out.println(e.getMessage());
		}
	}
	
	// default value when constructor has assignment
	@Test
	public void testingConstructorAssignment()
	{
		try
		{
			System.out.print("JUnit 4.0 Test [Assertions] - Constructor Assignment : ");
			assertTrue("SUCCESS", r.getHeight()==100 && r.getWidth()==100);
			System.out.println("SUCCESS.");
		}
		catch (AssertionError e)
		{
			System.out.println(e.getMessage());
		}
	}
	
	// return value should be correct (combination with if statement)
	// failed test
	@Test
	public void testingReturnValues() {
		System.out.print("JUnit 4.0 Test [Assertions] - Return value : ");
		
		try {
			assertTrue("SUCCESS", r.contains(90, 90));
			System.out.println("SUCCESS.");
		} catch (AssertionError e) {
			System.out.println(e.getMessage());
		}
		
		//assertThat(actual, matcher);
	}
	
	// testing for private function.
	@Test
	public void testingPrivateMethods() {
		System.out.print("JUnit 4.0 Test [Assertions] - Private Method : ");
		
		Method method;
		try {
			method = MyRectangle.class.getDeclaredMethod("checkInputs", String.class);
			method.setAccessible(true);
			Boolean result = (Boolean)method.invoke(r, "1");
			assertTrue("SUCCESS", result.booleanValue()); 
			System.out.println("SUCCESS.");
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void testingProtectedMethods() {
		System.out.print("JUnit 4.0 Test [Assertions] - Protected Method : ");
		
		
		Method method;
		try {
			method = MyRectangle.class.getDeclaredMethod("protectedMethod");
			method.setAccessible(true);
			method.invoke(r);
			System.out.println("SUCCESS.");
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
	
	//@Test(expected=java.lang.NumberFormatException.class)
	@Test
	public void testingExceptions() {
		System.out.print("JUnit 4.0 Test [Assertions] - Exceptions : ");
		
		Method method;
		try {
			method = MyRectangle.class.getDeclaredMethod("checkInputs", String.class);
			method.setAccessible(true);
			method.invoke(r, "s");
			System.out.println("SUCCESS.");
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
			NumberFormatException nfe = (NumberFormatException)e;
			throw nfe;
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void testingStaticFunction() {
		System.out.print("JUnit 4.0 Test [Assertions] - Static functions : ");
		
		MyRectangle.staticFunction();
		
		assertTrue("SUCCESS", true);
		
		System.out.println("SUCCESS");
	}

	public static void main(String[] args) {
		org.junit.runner.JUnitCore.main("RectangleTest");
	}
}
